package com.haixiaoke.saas.dept.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.haixiaoke.saas.common.constant.UserConstants;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.StringUtils;
import com.haixiaoke.saas.common.utils.TreeUtil.TreeUtil;
import com.haixiaoke.saas.dept.domain.Dept;
import com.haixiaoke.saas.dept.mapper.DeptMapper;
import com.haixiaoke.saas.dept.service.IDeptService;
import com.haixiaoke.saas.dept.domain.DeptTree;
import com.haixiaoke.saas.role.domain.Role;
import com.haixiaoke.saas.role.service.IRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 企业端部门管理Service业务层处理
 *
 * @author panda
 * @date 2023-12-27
 */
@Service
public class DeptServiceImpl implements IDeptService {
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private IRoleService iRoleService;

    /**
     * 查询企业端部门管理
     *
     * @param deptId 企业端部门管理主键
     * @return 企业端部门管理
     */
    @Override
    public Dept selectDeptByDeptId(Long deptId) {
        return deptMapper.selectDeptByDeptId(deptId);
    }

    /**
     * 查询企业端部门管理列表
     *
     * @param dept 企业端部门管理
     * @return 企业端部门管理
     */
    @Override
    public List<Dept> selectDeptList(Dept dept) {
        return deptMapper.selectDeptList(dept);
    }

    /**
     * 新增企业端部门管理
     *
     * @param bizDept 企业端部门管理
     * @return 结果
     */
    @Override
    @Transactional
    public int insertDept(Dept bizDept) {
        bizDept.setCreateTime(DateUtils.getNowDate());
        Dept dept = deptMapper.selectDeptByDeptId(bizDept.getParentId());
        if (ObjectUtil.isNotEmpty(dept)) {
            if (!UserConstants.DEPT_NORMAL.equals(dept.getStatus())) {
                throw new ServiceException("部门停用，不允许新增");
            }
            if (!bizDept.getParentId().equals(dept.getParentId())) {
                bizDept.setAncestors(dept.getAncestors() + "," + bizDept.getParentId());
            }
        } else {
            bizDept.setAncestors(String.valueOf(bizDept.getParentId()));
        }
        return deptMapper.insertDept(bizDept);
    }

    /**
     * 修改企业端部门管理
     *
     * @param bizDept 企业端部门管理
     * @return 结果
     */
    @Override
    @Transactional
    public int updateDept(Dept bizDept) {
        if (bizDept.getDeptId().equals(bizDept.getParentId())) {
            throw new ServiceException("数据异常，不能设置自己为父级结构");
        }
        bizDept.setUpdateTime(DateUtils.getNowDate());
        Dept parentDept = deptMapper.selectDeptByDeptId(bizDept.getParentId());
        Dept dept = deptMapper.selectDeptByDeptId(bizDept.getDeptId());
        if (ObjectUtil.isNotEmpty(parentDept) && ObjectUtil.isNotEmpty(dept)) {
            String newAncestors = parentDept.getAncestors() + "," + parentDept.getDeptId();
            String oldAncestors = dept.getAncestors();
            bizDept.setAncestors(newAncestors);
            updateDeptChildren(bizDept, newAncestors, oldAncestors);
        } else if (ObjectUtil.isEmpty(parentDept) && ObjectUtil.isNotEmpty(dept)) {
            String newAncestors = "0";
            String oldAncestors = dept.getAncestors();
            bizDept.setAncestors(newAncestors);
            updateDeptChildren(bizDept, newAncestors, oldAncestors);
        }
        return deptMapper.updateDept(bizDept);
    }

    private void updateDeptChildren(Dept bizDept, String newAncestors, String oldAncestors) {
        Date nowDate = DateUtils.getNowDate();
        List<Dept> deptList = deptMapper.selectDeptChildrenByDeptId(bizDept.getDeptId());
        for (Dept dept : deptList) {
            dept.setAncestors(dept.getAncestors().replaceFirst(oldAncestors, newAncestors));
            dept.setUpdateTime(nowDate);
            dept.setUpdateBy(bizDept.getUpdateBy());
        }
        if (!deptList.isEmpty()) {
            deptMapper.updateBatchDept(deptList);
        }
    }

    /**
     * 批量删除企业端部门管理
     *
     * @param deptIds 需要删除的企业端部门管理主键
     * @return 结果
     */
    @Override
    public int deleteDeptByDeptIds(Long[] deptIds) {
        return deptMapper.deleteDeptByDeptIds(deptIds);
    }

    /**
     * 删除企业端部门管理信息
     *
     * @param deptId 企业端部门管理主键
     * @return 结果
     */
    @Override
    public int deleteDeptByDeptId(Long deptId) {
        return deptMapper.deleteDeptByDeptId(deptId);
    }

    /**
     * 统计该部门下的所有正常状态的子部门
     *
     * @param deptId
     * @return
     */
    @Override
    public int selectNormalChildrenDeptById(Long deptId) {
        return deptMapper.selectNormalChildrenDeptById(deptId);
    }

    @Override
    public boolean checkDeptNameUnique(Dept dept) {
        Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId();
        Dept info = deptMapper.checkDeptNameUnique(dept);
        if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 创建树形结构
     *
     * @param dept
     * @return
     */
    @Override
    public List<DeptTree> buildTreeList(Dept dept) {
        List<DeptTree> deptLists = deptMapper.selectDeptTreeList(dept);
        List<DeptTree> deptTrees = TreeUtil.generateTree(deptLists);
        return deptTrees;
    }

    /**
     * 查询是否有下级部门
     *
     * @param deptId
     * @return
     */
    @Override
    public boolean hasChildByDeptId(Long deptId) {
        int result = deptMapper.hasChildByDeptId(deptId);
        return result > 0;
    }

    /**
     * 查询部门是否有用户
     *
     * @param deptId
     * @return
     */
    @Override
    public boolean checkDeptExistUser(Long deptId) {
        int result = deptMapper.checkDeptExistUser(deptId);
        return result > 0;
    }

    @Override
    public int softDeleteDeptByDeptId(Long deptId) {
        return deptMapper.softDeleteDeptByDeptId(deptId);
    }

    @Override
    public List<Long> selectDeptListByRoleId(Long roleId) {
        Role role = iRoleService.selectBizRoleByRoleId(roleId);
        return deptMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly());
    }

    @Override
    public Dept selectDeptByDeptName(String deptName) {
        return deptMapper.selectDeptByDeptName(deptName);
    }

    private List<Dept> selectBuildTreeList(List<Dept> deptList) {
        List<Dept> list = new ArrayList<>();
        List<Long> groupIds = deptList.stream().map(Dept::getDeptId).collect(Collectors.toList());
        for (Dept dept : deptList) {
            // 如果是根节点，则获取子节点所有数据
            if (!groupIds.contains(dept.getParentId())) {
                buildChildTreeList(deptList, dept);
                list.add(dept);
            }
        }
        if (list.isEmpty()) {
            list = deptList;
        }
        return list;
    }

    private void buildChildTreeList(List<Dept> deptList, Dept dept) {
        // 获取子节点所有数据
        List<Dept> childList = getChildList(deptList, dept);
        dept.setChildren(childList);
        for (Dept bizDept : childList) {
            if (hashChild(deptList, bizDept)) {
                buildChildTreeList(deptList, dept);
            }
        }
    }

    private boolean hashChild(List<Dept> deptList, Dept dept) {
        return !getChildList(deptList, dept).isEmpty();
    }

    private List<Dept> getChildList(List<Dept> deptList, Dept dept) {
        List<Dept> list = new ArrayList<>();
        Iterator<Dept> iterator = deptList.iterator();
        while (iterator.hasNext()) {
            Dept bizDept = (Dept) iterator.next();
            if (bizDept.getParentId() != null && bizDept.getParentId().equals(dept.getDeptId())) {
                list.add(bizDept);
            }
        }
        return list;
    }
}
